using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace Deferred.Library.Input
{
    /// <summary>
    /// 
    /// </summary>
    public delegate void KeyFunction();

    /// <summary>
    /// 
    /// </summary>
    public interface IKeyboardHandler
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <param name="function"></param>
        void AddBinding(Keys key, KeyFunction function);
    }

    /// <summary>
    /// 
    /// </summary>
    public class KeyboardHandler : IKeyboardHandler
    {
        private IServiceProvider serviceProvider;
        private KeyboardState oldState;
        private Dictionary<Keys, List<KeyFunction>> bindings;
        private IFocusHelper focusHelper;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceProvider"></param>
        public KeyboardHandler(IServiceProvider serviceProvider)
        {
            this.serviceProvider = serviceProvider;
            bindings = new Dictionary<Keys, List<KeyFunction>>();
        }

        /// <summary>
        /// 
        /// </summary>
        public void Initialize()
        {
            focusHelper = (IFocusHelper)serviceProvider.GetService(typeof(IFocusHelper));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="gameTime"></param>
        public void Update(GameTime gameTime)
        {
            KeyboardState currentState = Keyboard.GetState();

            if (null == focusHelper || focusHelper.GameHasFocus)
            {
                if (oldState != null)
                {
                    foreach (Keys key in bindings.Keys)
                    {
                        if (currentState.IsKeyUp(key) && oldState.IsKeyDown(key))
                        {
                            foreach (KeyFunction action in bindings[key])
                            {
                                action();
                            }
                        }
                    }
                }
            }

            oldState = currentState;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <param name="function"></param>
        public void AddBinding(Keys key, KeyFunction function)
        {
            if (!bindings.ContainsKey(key))
            {
                bindings[key] = new List<KeyFunction>();
            }

            bindings[key].Add(function);
        }
    }
}